package com.dd.consulprovider.consul_lock;

import java.util.List;

import org.joda.time.LocalDateTime;

import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.Response;
import com.ecwid.consul.v1.kv.model.PutParams;
import com.ecwid.consul.v1.session.model.NewSession;
import com.ecwid.consul.v1.session.model.Session;

public class Lock {	 

    private static final String prefix = "lock/";  // 同步锁参数前缀 

    private ConsulClient consulClient;

    private String sessionName;

    private String sessionId = null;

    private String lockKey; 

    /**

     *

     * @param consulClient

     * @param sessionName   同步锁的session名称

     * @param lockKey       同步锁在consul的KV存储中的Key路径，会自动增加prefix前缀，方便归类查询

     */

    public Lock(ConsulClient consulClient, String sessionName, String lockKey) {

        this.consulClient = consulClient;

        this.sessionName = sessionName;

        this.lockKey = prefix + lockKey;

    }

 

    /**

     * 获取同步锁

     *

     * @param block     是否阻塞，直到获取到锁为止

     * @return

     */

    public Boolean lock(boolean block) {

        if (sessionId != null) {

            throw new RuntimeException(sessionId + " - Already locked!");

        }
        
        sessionId = createSession(sessionName);
        
        System.out.println("sessionId="+sessionId);

        while(true) {

            PutParams putParams = new PutParams();

            putParams.setAcquireSession(sessionId);
            
            String value = "lock:" + LocalDateTime.now();
            
            System.out.println(Thread.currentThread().getName()+" 设置key="+lockKey+",value="+value);
            
            if(consulClient.setKVValue(lockKey, value, putParams).getValue()) {
            	
            	System.out.println(Thread.currentThread().getName()+" 设置key="+lockKey+",value="+value+"====成功");

                return true;                
                

            } else if(block) {
            	System.out.println(Thread.currentThread().getName()+" 设置key="+lockKey+",value="+value+"====失败block");
                continue;

            } else {
            	System.out.println(Thread.currentThread().getName()+" 设置key="+lockKey+",value="+value+"====失败");
                return false;

            }

        }

    }

 

    /**

     * 释放同步锁

     *

     * @return

     */

    public Boolean unlock() {

        PutParams putParams = new PutParams();

        putParams.setReleaseSession(sessionId);
        
        String value = "unlock:" + LocalDateTime.now();
        
        System.out.println(Thread.currentThread().getName()+" 设置key="+lockKey+",value="+value);

        boolean result = consulClient.setKVValue(lockKey, value, putParams).getValue();
        
        printSession();

        consulClient.sessionDestroy(sessionId, null);        
        
        System.out.println("sessionDestroy================");
        printSession();

        return result;

    }
    
    public void printSession(){
    	Response<List<Session>> response = consulClient.getSessionList(null);
    	List<Session> list = response.getValue();
    	for (Session session : list) {
			System.out.println(session);
		}
    }
 

    /**

     * 创建session

     * @param sessionName

     * @return

     */

    private String createSession(String sessionName) {

        NewSession newSession = new NewSession();

        newSession.setName(sessionName);

        System.out.println(Thread.currentThread().getName()+" 创建session");
        
        return consulClient.sessionCreate(newSession, null).getValue();

    }

}
